package mysql

import (
	"fmt"
	"time"

	"gorm.io/gorm"
)

type Student struct {
	gorm.Model
	Name     string
	Age      int
	BirthDay time.Time
}

// 钩子函数
func (student *Student) BeforeSave(tx *gorm.DB) (err error) {
	fmt.Println("BeforeSave...")
	return nil
}

func (student *Student) BeforeCreate(tx *gorm.DB) (err error) {
	fmt.Println("BeforeCreate...")
	return nil
}

func (student *Student) AfterSave(tx *gorm.DB) (err error) {
	fmt.Println("AfterSave...")
	return nil
}

func (student *Student) AfterCreate(tx *gorm.DB) (err error) {
	fmt.Println("AfterCreate...")
	return nil
}

// 建表
func CreateTable() {
	DB.AutoMigrate(&Student{})
}

// 插入数据
func Insert1() {
	student := Student{Name: "周五", Age: 20, BirthDay: time.Now()}
	//ret := DB.Create(&student)
	// 跳过钩子函数
	ret := DB.Session(&gorm.Session{SkipHooks: true}).Create(&student)

	// 受影响行数
	fmt.Printf("ret.RowsAffected: %v\n", ret.RowsAffected)
	fmt.Printf("student.ID: %v\n", student.ID)
}

// 指定字段插入
func Insert2() {
	student := Student{Name: "周五", Age: 20, BirthDay: time.Now()}
	// 只插入指定字段
	ret := DB.Select("Name", "Age").Create(&student)
	// 受影响行数
	fmt.Printf("ret.RowsAffected: %v\n", ret.RowsAffected)
	fmt.Printf("student.ID: %v\n", student.ID)

	student2 := Student{Name: "周五", Age: 20, BirthDay: time.Now()}
	// 忽略指定字段插入
	ret = DB.Omit("Name", "Age", "CreatedAt").Create(&student2)
	// 受影响行数
	fmt.Printf("ret.RowsAffected: %v\n", ret.RowsAffected)
	fmt.Printf("student.ID: %v\n", student2.ID)
}

func Insert3() {
	var students = []Student{{Name: "name1"}, {Name: "name2"}}
	// 切片批量插入
	DB.Omit("BirthDay").Create(&students)
	// 指定批量值
	// DB.CreateInBatches(students, 100)
	/*
		设置批量值的方法
		1. 获取连接时  设置配置
		db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
		CreateBatchSize: 1000,
		})
		2. session中配置
		db := db.Session(&gorm.Session{CreateBatchSize: 1000})
	*/

	for _, v := range students {
		fmt.Printf("v.ID: %v\n", v.ID)
	}

}

func Insert4() {
	// 只会插入给定字段
	DB.Model(&Student{}).Create(map[string]interface{}{
		"Name": "zhou1", "Age": 20,
	})

	DB.Model(&Student{}).Create([]map[string]interface{}{
		{"Name": "zhou2", "Age": 22},
		{"Name": "zhou3", "Age": 23},
	})
}

func Insert5() {
	// 其余高级使用
	/*
		   	1. SQL表达式 ： 函数。。。
		   	db.Model(User{}).Create(map[string]interface{}{
		     "Name": "jinzhu",
		     "Location": clause.Expr{SQL: "ST_PointFromText(?)", Vars: []interface{}{"POINT(100 100)"}},
		   })
		   2. 关联创建
		   3. 默认值标签
		   4. Upsert冲突更新方法
		   // 冲突时什么也不做
		   db.Clauses(clause.OnConflict{DoNothing: true}).Create(&user)
		   // id冲突时更新指定列
		   // 冲突时更新除主键外的所有字段
		   db.Clauses(clause.OnConflict{
			UpdateAll: true,
			}).Create(&users)

	*/
}
